Add instruction execution limit to prevent infinite loops #18679
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/18679
Note: Links to docs will display an error until the docs builds have been completed. ❌ 1 New Failure, 2 Unrelated FailuresAs of commit 0047105 with merge base 5e8a0df ( NEW FAILURE - The following job has failed:
BROKEN TRUNK - The following jobs failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
There was a problem hiding this comment.
Pull request overview
Adds a safety guard in the ExecuTorch runtime to prevent Method::execute() from hanging indefinitely when executing malformed programs that can loop forever (e.g., self-looping jump instructions).
Changes:
- Introduces a compile-time configurable maximum instruction execution count (
ET_MAX_INSTRUCTIONS, default 10,000,000). - Tracks executed instruction count inside
Method::execute()and aborts with an error when the limit is exceeded. - Emits an error log when the limit is hit and resets execution state before returning.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ". Possible infinite loop detected.", | ||
| kMaxInstructions, | ||
| step_state_.chain_idx); |
There was a problem hiding this comment.
The log message doesn’t tell users how to remediate legitimate long-running models that exceed the default limit. Consider including the current instruction index (step_state_.instr_idx) and a hint that the limit is configurable via -DET_MAX_INSTRUCTIONS (or ET_MAX_INSTRUCTIONS) so operators can adjust it without digging into the code.
| ". Possible infinite loop detected.", | |
| kMaxInstructions, | |
| step_state_.chain_idx); | |
| " at instruction %" ET_PRIsize_t | |
| ". Possible infinite loop detected. For legitimate long-running " | |
| "models, increase the limit via -DET_MAX_INSTRUCTIONS " | |
| "(ET_MAX_INSTRUCTIONS).", | |
| kMaxInstructions, | |
| step_state_.chain_idx, | |
| step_state_.instr_idx); |
| if (instruction_count >= kMaxInstructions) { | ||
| ET_LOG( | ||
| Error, | ||
| "Instruction execution limit (%" ET_PRIsize_t | ||
| ") exceeded in chain %" ET_PRIsize_t | ||
| ". Possible infinite loop detected.", | ||
| kMaxInstructions, | ||
| step_state_.chain_idx); | ||
| step_state_ = StepState{0, 0}; | ||
| return Error::InvalidState; | ||
| } |
There was a problem hiding this comment.
This introduces a new failure mode in Method::execute() that should be covered by a regression test. Consider adding a unit test that builds a minimal flatbuffer program with a self-looping jump (or otherwise forces an infinite instruction loop) and asserts execute() fails once the instruction limit is exceeded (ideally with a small ET_MAX_INSTRUCTIONS value for the test target to keep runtime short).
|
@claude review |
|
Claude finished @lucylq's task in 1m 12s —— View job Review of PR #18679
Good defensive measure. The change is small and well-scoped. A few observations: 1. Error code: The current code returns 2. Negative/zero Since static_assert(ET_MAX_INSTRUCTIONS > 0, "ET_MAX_INSTRUCTIONS must be positive");This is a minor point — arguably someone setting it to 0 intends to "disable" it — but if the intent is that the limit is always active, a static assert is worth adding. 3. Log message could include instruction index and remediation hint The current log shows the limit and chain index, but not 4. The 5. No dedicated test for the new failure mode The test plan references existing Summary: The change is sound and addresses a real denial-of-service vector from malformed programs. The two actionable suggestions are (1) using |
…ORCH-23) JumpFalseCall instructions can set destination_instruction to themselves, creating an infinite loop that hangs the runtime. This adds a configurable instruction counter (default 10M, overridable via -DET_MAX_INSTRUCTIONS) to Method::execute() that returns Error::InvalidState if exceeded. This PR was authored with the assistance of Claude.
JumpFalseCall instructions can set destination_instruction to themselves, creating an infinite loop that hangs the runtime. This adds a configurable instruction counter (default 10M, overridable via -DET_MAX_INSTRUCTIONS) to Method::execute() that returns Error::InvalidState if exceeded.
This PR was authored with the assistance of Claude.
Test plan
Existing tests